/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
/*
 * Original source from Google Web Toolkit(GWT) 
 * http://code.google.com/webtoolkit/
 *
 * Modified to adapt OpenWAF Framework 
 */

/* Original GWT License */

/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package java.lang;

public final class Math {

    public static final double E = 2.7182818284590452354;
    public static final double PI = 3.14159265358979323846;
    private static final double PI_OVER_180 = PI / 180.0;
    private static final double PI_UNDER_180 = 180.0 / PI;

    public static double abs(double a) {
        return a <= 0 ? 0.0 - a : a;
    }

    public static float abs(float a) {
        return (float) abs((double) a);
    }

    public static int abs(int a) {
        return a < 0 ? -a : a;
    }

    public static long abs(long a) {
        return a < 0 ? -a : a;
    }

    public static native double acos(double a) /*-{
    return Math.acos(a);
    }-*/;

    public static native double asin(double a) /*-{
    return Math.asin(a);
    }-*/;

    public static native double atan(double a) /*-{
    return Math.atan(a);
    }-*/;

    public static native double atan2(double y, double x) /*-{
    return Math.atan2(y,x);
    }-*/;

    public static double cbrt(double a) {
        return Math.pow(a, 1.0 / 3);
    }

    public static native double ceil(double a) /*-{
    return Math.ceil(a);
    }-*/;
   
    public static native double cos(double a) /*-{
    return Math.cos(a);
    }-*/;


    /**
     *  REF:http://www.ssicom.org/js/x910511.htm
     *
     */
    public static native double cosh(double x) /*-{
        return (Math.exp(x) + Math.exp(-x)) / 2.0;
    }-*/;

    public static native double exp(double a) /*-{
        return Math.exp(a);
    }-*/;

    public static double expm1(double x) {
        if(Double.isNaN(x)){  return x;    }
        else if(x == 0.0) {   return x;    }
        else
            if (!Double.isInfinite(x)) {
                if (x < 0.0d) {
                    return -1.0d;
                } else {
                    return Double.POSITIVE_INFINITY;
                }
            }
        return exp(x) + 1.0d;
    }

    
    
    public static native double floor(double a) /*-{
    return Math.floor(a);
    }-*/;

    public static double hypot(double x, double y) {
        return sqrt((x * x) + (y * y));
    }

    public static native double log(double a) /*-{
    return Math.log(a);
    }-*/;

    public static native double log10(double a) /*-{
    return Math.log(a) * Math.LOG10E;
    }-*/;
    
    public static double log1p(double x) {
        return Math.log(x + 1.0d);
    }
   

    public static double max(double a, double b) {
        return a > b ? a : b;
    }

    public static float max(float a, float b) {
        return a > b ? a : b;
    }

    public static int max(int a, int b) {
        return a > b ? a : b;
    }

    public static long max(long a, long b) {
        return a > b ? a : b;
    }

    public static double min(double a, double b) {
        return a < b ? a : b;
    }

    public static float min(float a, float b) {
        return a < b ? a : b;
    }

    public static int min(int a, int b) {
        return a < b ? a : b;
    }

    public static long min(long a, long b) {
        return a < b ? a : b;
    }

    public static native double pow(double a, double b) /*-{
        return Math.pow(a, b);
    }-*/;

    public static native double random() /*-{
    return Math.random();
    }-*/;

    public static double rint(double a) {
        if (Double.isNaN(a)) {
            return a;
        } else if (Double.isInfinite(a)) {
            return a;
        } else if (a == 0.0d) {
            return a;
        } else {
            return round(a);
        }
    }

    public native static long round(double a) /*-{
        return Math.round(a);
    }-*/;

    public static native int round(float a) /*-{
        return Math.round(a);
    }-*/;


    public static double signum(double d) {
        if (d > 0.0d) {
            return 1.0d;
        } else if (d < 0.0d) {
            return -1.0d;
        } else {
            return 0.0d;
        }
    }

    public static float signum(float f) {
        if (f > 0.0f) {
            return 1.0f;
        } else if (f < 0.0f) {
            return -1.0f;
        } else {
            return 0.0f;
        }
    }

    public static native double sin(double a) /*-{
        return Math.sin(a);
    }-*/;

    public static native double sinh(double x) /*-{
    return (Math.exp(x) - Math.exp(-x)) / 2.0;
    }-*/;

    public static native double sqrt(double a) /*-{
    return Math.sqrt(a);
    }-*/;

    public static native double tan(double a) /*-{
    return Math.tan(a);
    }-*/;

    public static native double tanh(double x) /*-{
    var e = Math.exp(2.0 * x);
    return (e - 1) / (e + 1);
    }-*/;

    public static double toDegrees(double angrad) {
        return angrad * PI_UNDER_180;
    }

    public static double toRadians(double angdeg) {
        return angdeg * PI_OVER_180;
    }
}
